home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / ifuncs.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  10KB  |  515 lines

  1. /* --------------------------------- ifuncs.c ------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* Handle integer trig and math functions
  8. */
  9.  
  10. #ifdef GEN_TAB
  11. #undef USE_ASM
  12. #endif
  13.  
  14. #include "fly.h"
  15.  
  16.  
  17. #undef ihypot2d
  18. extern Ushort FAR FASTCALL
  19. ihypot2d (int x, int y)
  20. {
  21.     return (SQRT (x*(long)x + y*(long)y));
  22. }
  23.  
  24. #undef ihypot3d
  25. extern Ushort FAR FASTCALL
  26. ihypot3d (VECT A)
  27. {
  28.     return (SQRT (A[X]*(long)A[X] + A[Y]*(long)A[Y] + A[Z]*(long)A[Z]));
  29. }
  30.  
  31. #ifndef EXT_TABS
  32. #include <math.h>
  33. #endif
  34.  
  35. /* This part initializes the constant tables.
  36.  * It either #includes constant ones or calculates them.
  37. */
  38.  
  39. #ifdef EXT_TABS
  40. #include "itabs.c"
  41.  
  42. extern int FAR
  43. funcs_init (void)
  44. {return (0);}
  45.  
  46. extern void FAR
  47. funcs_term (void)
  48. {}
  49.  
  50. #else
  51.  
  52. /* angles are stored such that -pi..0..pi radians is 0x8000..0..0x7fff
  53. */
  54.  
  55. #define    P3_4    ((1024/4)*3)
  56.  
  57. static short    NEAR log_tab[201] = {0};    /* exponential -100...+100 */
  58. static short    NEAR sin_tab[1024+1] = {0};        /* 0..90 */
  59. static ANGLE    NEAR asin_tab0[1024+1] = {0};        /* 0......1/4 */
  60. static ANGLE    NEAR asin_tab1[P3_4+1] = {0};        /* 0......3/4 */
  61. static ANGLE    NEAR asin_tab2[P3_4+1] = {0};        /* 3/4....15/16 */
  62. static ANGLE    NEAR asin_tab3[1024+1] = {0};        /* 15/16..1 */
  63. static ANGLE    NEAR atan_tab1[P3_4+1] = {0};        /* 0......3/4 */
  64. static ANGLE    NEAR atan_tab2[P3_4+1] = {0};        /* 3/4....15/16 */
  65. static ANGLE    NEAR atan_tab3[1024+1] = {0};        /* 15/16..1 */
  66. static Ushort    NEAR sqrtab[256+1] = {0};
  67.  
  68. LOCAL_FUNC void NEAR
  69. set_log (void)
  70. {
  71.     int    i, v, s;
  72.  
  73.     v = FONE;                /* 100% start */
  74.     s = FCON(0.955);            /* 4.5%   step */
  75.     for (i = 100; i > 0; --i) {        /* about 100 steps */
  76.         log_tab[100+i] = v;
  77.         log_tab[100-i] = -v;
  78.         v = fmul (v, s);
  79.         i = iabs (i);            /* scare gcc bug */
  80.     }
  81.     log_tab[100] = 0;            /* nice zero */
  82. }
  83.  
  84. LOCAL_FUNC short NEAR
  85. my_round (double f)
  86. {
  87.     return ((short)((f<0) ? f-0.5 : f+0.5));
  88. }
  89.  
  90. /* Fill in the trig tables.
  91. */
  92. LOCAL_FUNC void NEAR
  93. set_trig (void)
  94. {
  95.     double    s, c, t, d, sd, cd, pi;
  96.     int    i;
  97.  
  98.     pi = atan(1.0)*4;
  99.     d = pi/2048;            /* 0...pi */
  100.     sd = sin (d);
  101.     cd = cos (d);
  102.     s = 0.0;
  103.     c = 1.0*FONE;
  104.  
  105.     for (i = 0; i <= 1024; ++i) {
  106.         sin_tab[i] = my_round (s);
  107.         t = c*sd+s*cd;
  108.         c = c*cd-s*sd;
  109.         s = t;
  110.     }
  111.  
  112.     for (i = 0; i <= 1024; ++i)
  113.         asin_tab0[i] = (ANGLE)my_round (asin (i/16.0/1024.0)
  114.                 *0x08000/pi);
  115.     for (i = 0; i <= P3_4; ++i)
  116.         asin_tab1[i] = (ANGLE)my_round (asin (i*3.0/4.0/P3_4)
  117.                 *0x08000/pi);
  118.     for (i = 0; i <= P3_4; ++i)
  119.         asin_tab2[i] = (ANGLE)my_round (asin (
  120.                     3.0/4.0+i*(15.0/16.0-3.0/4.0)/P3_4)
  121.                     *0x08000/pi);
  122.     for (i = 0; i <= 1024; ++i)
  123.         asin_tab3[i] = (ANGLE)my_round (asin (
  124.                     15.0/16.0+i*(1.0-15.0/16.0)/1024)
  125.                     *0x08000/pi);
  126.  
  127.     for (i = 0; i <= P3_4; ++i)
  128.         atan_tab1[i] = (ANGLE)my_round (atan (i*3.0/4.0/P3_4)
  129.                 *0x08000/pi);
  130.     for (i = 0; i <= P3_4; ++i)
  131.         atan_tab2[i] = (ANGLE)my_round (atan (
  132.                     3.0/4.0+i*(15.0/16.0-3.0/4.0)/P3_4)
  133.                     *0x08000/pi);
  134.     for (i = 0; i <= 1024; ++i)
  135.         atan_tab3[i] = (ANGLE)my_round (atan (
  136.                     15.0/16.0+i*(1.0-15.0/16.0)/1024)
  137.                     *0x08000/pi);
  138. }
  139.  
  140. #undef P3_4
  141.  
  142. LOCAL_FUNC Ushort NEAR
  143. lsqrt (Ulong x)                /* used for initialization only */
  144. {
  145.     long    e;
  146.     Ulong    r, t;
  147.  
  148.     if (x & 0xffff0000L)
  149.         r = 662 + x / 17916;
  150.     else if (x & 0x0000ff00L)
  151.         r = 3 + x / 70;
  152.     else
  153.         r = 2 + x / 11;
  154.  
  155.     do {
  156.         t = x / r;
  157.         e = (long)(r - t) / 2;
  158.         r = (r + t) / 2;
  159.     } while (e);
  160.     return ((Ushort)r);
  161. }
  162.  
  163. LOCAL_FUNC void NEAR
  164. set_lsqrt (void)
  165. {
  166.     int    i;
  167.  
  168.     for (i = 0; i < 256; ++i)
  169.         sqrtab[i] = lsqrt (i*256L*256L*256L);
  170.     sqrtab[256] = 0xffffU;
  171. }
  172.  
  173. extern int FAR
  174. init_funcs (void)
  175. {
  176.     set_log ();
  177.     set_trig ();
  178.     set_lsqrt ();
  179.     return (0);
  180. }
  181.  
  182. extern void FAR
  183. term_funcs (void)
  184. {}
  185.  
  186. #endif
  187.  
  188. /* Integer trig and math functions.
  189. */
  190. extern short FAR FASTCALL
  191. lin2log (short linear)
  192. {
  193.     return (fmul (log_tab[100+linear], 100));
  194. }
  195.  
  196. extern short FAR FASTCALL
  197. my_sinc (ANGLE d)
  198. {
  199.     int    f, l, ind;
  200.  
  201.     ind = 0;
  202.     if (d < 0) {
  203.         ;
  204.         if ((d = -d) < 0)    /* -180 degrees! */
  205.             return (0);
  206.         ind = -1;
  207.     }
  208.     if (d > D90) {
  209.         d -= D180;
  210.         d = -d;
  211.     }
  212.  
  213.     f = d&15;            /* d%16 */
  214.     d >>= 4;            /* d/16 */
  215.     l = sin_tab[d];
  216.     l += (8+(sin_tab[d+1] - l)*f)>>4;    /* (8+(h-l)*f)/16; */
  217.  
  218.     return ((short)((l^ind)-ind));
  219. }
  220.  
  221. extern ANGLE FAR FASTCALL
  222. my_asin (int d)
  223. {
  224.     int    f;
  225.     ANGLE    l, ind;
  226.  
  227.     ind = 0;
  228.     if (d < 0) {
  229.         d = -d;
  230.         ind = -1;
  231.     }
  232.  
  233.     if (d < FONE/16)        /* 0..1/16 */
  234.         l = asin_tab0[d];
  235.     else if (d < (FONE/4)*3) {    /* 1/16..3/4 */
  236.         f = d&15;
  237.         d = d>>4;
  238.         l = asin_tab1[d];
  239.         l += (8+(asin_tab1[d+1] - l)*f)>>4;
  240.     } else if (d < (FONE/16)*15) {    /* 3/4..15/16 */
  241.         d -= (FONE/4)*3;    /* 0..1/4 */
  242.         f = d&3;
  243.         d = d>>2;
  244.         l = asin_tab2[d];
  245.         l += (2+(asin_tab2[d+1] - l)*f)/4;
  246.     } else {            /* 15/16..1 */
  247.         if (d > FONE)
  248.             d = FONE;
  249.         d -= (FONE/16)*15;    /* 0..1/16 */
  250.         l = asin_tab3[d];
  251.     }
  252.     return ((ANGLE)((l^ind)-ind));
  253. }
  254.  
  255. extern ANGLE FAR FASTCALL
  256. my_atan (int y, int x)
  257. {
  258.     int    eight, f, i, d;
  259.     ANGLE    l;
  260.  
  261.     eight = 0;
  262.     if (y < 0) {
  263.         y = -y;
  264.         if (y < 0) {
  265.             y = -(y/2);
  266.             x = x/2;
  267.         }
  268.         eight = 1;
  269.     }
  270.     if (x < 0) {
  271.         x = -x;
  272.         if (x < 0) {
  273.             y = y/2;
  274.             x = -(x/2);
  275.         }
  276.         eight += 2;
  277.     }
  278.     if (y > x) {
  279.         d = y;
  280.         y = x;
  281.         x = d;
  282.         eight += 4;
  283.     } else if (x == 0)
  284.         return (0);
  285.  
  286.     d = fdiv (y, x);        /* temp */
  287.  
  288.     if (d < (FONE/4)*3) {        /* 0..3/4 */
  289.         f = d&15;
  290.         i = d>>4;
  291.         l = atan_tab1[i];
  292.         l += (8+(atan_tab1[i+1] - l)*f)>>4;
  293.     } else if (d < (FONE/16)*15) {    /* 3/4..15/16 */
  294.         d -= (FONE/4)*3;
  295.         f = d&3;
  296.         i = d>>2;
  297.         l = atan_tab2[i];
  298.         l += (2+(atan_tab2[i+1] - l)*f)>>2;
  299.     } else {            /* 15/16..1 */
  300.         if (d > FONE)
  301.             d = FONE;
  302.         d -= (FONE/16)*15;
  303.         l = atan_tab3[d];
  304.     }
  305.  
  306.     switch (eight) {
  307.     case 0:                /* ++ */
  308.         return (l);
  309.     case 1:                /* -+ */
  310.         return (-l);
  311.     case 2:                /* +- */
  312.         return (D180-l);
  313.     case 3:                /* -- */
  314.         return (D180+l);
  315.     case 4:                /* ++ rev */
  316.         return (D90-l);
  317.     case 5:                /* -+ rev */
  318.         return (-D90+l);
  319.     case 6:                /* +- rev */
  320.         return (D90+l);
  321.     case 7:                /* -- rev */
  322.         return (-D90-l);
  323.     }
  324.     return (0);            /* never reached */
  325. }
  326.  
  327. extern Ushort FAR FASTCALL
  328. my_sqrt (Ulong x)
  329. {
  330.     register Uint    r, t;
  331.     register int    e;
  332.  
  333.     if (x >= 0x00010000UL)
  334.         if (x >= 0x01000000UL)
  335.             if (x >= 0xfffe0001UL)
  336.                 return (0xffffU);
  337.             else
  338.                 r = sqrtab[(x>>24)+1];
  339.         else
  340.             r = sqrtab[(x>>16)+1] >> 4;
  341.     else if ((Uint)x >= 0x0100U)
  342.         r = sqrtab[((Uint)x>>8)+1] >> 8;
  343.     else
  344.         return (sqrtab[x] >> 12);
  345.  
  346.     do {
  347.         t = (Uint)(x / r);
  348.         e = (int)(r - t) / 2;
  349.         r -= e;
  350.     } while (e);
  351.  
  352.     return ((Ushort)t);
  353. }
  354.  
  355. extern Ulong FAR FASTCALL
  356. lhypot3d (LVECT A)        /* a bit of a cheat, but good enough! */
  357. {
  358.     Ulong    x, y, z;
  359.     Uint    f, xyz;
  360.  
  361.     x = labs(A[X]);
  362.     y = labs(A[Y]);
  363.     z = labs(A[Z]);
  364.     xyz = (Uint)((x/2+y/2+z/2) >> 15);
  365.     for (f = 1; xyz; xyz /= 2, f *= 2) {
  366.         x /= 2;
  367.         y /= 2;
  368.         z /= 2;
  369.     }
  370.     return (f * (Ulong)SQRT (x*x + y*y + z*z));
  371. }
  372.  
  373. extern Ulong FAR FASTCALL
  374. ldist3d (LVECT A, LVECT B)
  375. {
  376.     LVECT    LL;
  377.  
  378.     Vsub (LL, A, B);
  379.     return (lhypot3d (LL));
  380. }
  381.  
  382. extern Ushort FAR FASTCALL
  383. est_hyp (register int x, register int y, register int z)
  384. {
  385.     register Uint    d;
  386.  
  387.     if (x < 0)
  388.         x = -x;
  389.     if (y < 0)
  390.         y = -y;
  391.     if (z < 0)
  392.         z = -z;
  393.     if (x >= y)
  394.         if (x >= z)
  395.             d = x + ((Uint)(y+z)>>2);    /* x > y,z */
  396.         else
  397.             d = z + ((Uint)(y+x)>>2);    /* z > x > y */
  398.     else
  399.         if (y >= z)
  400.             d = y + ((Uint)(x+z)>>2);    /* y > x,z */
  401.         else
  402.             d = z + ((Uint)(x+y)>>2);    /* z > y > x */
  403.     return (d > 0x7fffU ? 0x7fff : d);
  404. }
  405.  
  406. extern Ushort FAR FASTCALL
  407. est_dist (LVECT R1, LVECT R2)
  408. {
  409.     long    x, y, z;
  410.  
  411.     x = (R1[X] - R2[X])/VONE;
  412.     if (x < 0)
  413.         x = -x;
  414.     if (x > 0x7fffL)
  415.         return (0x7fff);
  416.     y = (R1[Y] - R2[Y])/VONE;
  417.     if (y < 0)
  418.         y = -y;
  419.     if (y > 0x7fffL)
  420.         return (0x7fff);
  421.     z = (R1[Z] - R2[Z])/VONE;
  422.     if (z < 0)
  423.         z = -z;
  424.     if (z > 0x7fffL)
  425.         return (0x7fff);
  426.     return (est_hyp ((int)x, (int)y, (int)z));
  427. }
  428.  
  429. /* This part generates the constant tables.
  430. */
  431.  
  432. #ifdef GEN_TAB
  433.  
  434. /* We need 'status' and 'LogPrintf' for debug.c
  435. */
  436. struct status    NEAR st = {0};        /* needed for debug.c */
  437.  
  438. extern int FAR
  439. LogPrintf (const char *fmt, ...)
  440. {
  441.     va_list        ap;
  442.     int        i;
  443.  
  444.     va_start (ap, fmt);
  445.     i = vfprintf (stderr, fmt, ap);
  446.     va_end (ap);
  447.  
  448.     return (i);
  449. }
  450.  
  451. LOCAL_FUNC void NEAR
  452. emit_short (char *q, char *name, short *p, int size)
  453. {
  454.     int    i;
  455.  
  456.     size /= sizeof (*p);
  457.     printf ("%s short %s[] = {", q, name);
  458.     for (i = 0; i < size; ++i) {
  459.         if (!(i%8))
  460.             printf ("\n   ");
  461.         printf ("%hd%s ", *p++, (i < size-1) ? "," : "");
  462.     }
  463.     printf ("\n};\n");
  464. }
  465.  
  466. LOCAL_FUNC void NEAR
  467. emit_Ushort (char *q, char *name, Ushort *p, int size)
  468. {
  469.     int    i;
  470.  
  471.     size /= sizeof (*p);
  472.     printf ("%s Ushort %s[] = {", q, name);
  473.     for (i = 0; i < size; ++i) {
  474.         if (!(i%8))
  475.             printf ("\n   ");
  476.         printf ("%hu%s ", *p++, (i < size-1) ? "," : "");
  477.     }
  478.     printf ("\n};\n");
  479. }
  480.  
  481. LOCAL_FUNC void NEAR
  482. emit_angle (char *q, char *name, ANGLE *p, int size)
  483. {
  484.     int    i;
  485.  
  486.     size /= sizeof (*p);
  487.     printf ("%s ANGLE %s[] = {", q, name);
  488.     for (i = 0; i < size; ++i) {
  489.         if (!(i%8))
  490.             printf ("\n   ");
  491.         printf ("%hd%s ", *p++, (i < size-1) ? "," : "");
  492.     }
  493.     printf ("\n};\n");
  494. }
  495.  
  496. extern int
  497. main (int argc, char *argv[])
  498. {
  499.     init_funcs ();
  500.     emit_short  ("static", "FAR log_tab",   log_tab,   sizeof (log_tab));
  501.     emit_short  ("",       "NEAR sin_tab",   sin_tab,   sizeof (sin_tab));
  502.     emit_Ushort ("static", "FAR sqrtab",    sqrtab,    sizeof (sqrtab));
  503.     emit_angle  ("static", "FAR asin_tab0", asin_tab0, sizeof (asin_tab0));
  504.     emit_angle  ("static", "FAR asin_tab1", asin_tab1, sizeof (asin_tab1));
  505.     emit_angle  ("static", "FAR asin_tab2", asin_tab2, sizeof (asin_tab2));
  506.     emit_angle  ("static", "FAR asin_tab3", asin_tab3, sizeof (asin_tab3));
  507.     emit_angle  ("static", "FAR atan_tab1", atan_tab1, sizeof (atan_tab1));
  508.     emit_angle  ("static", "FAR atan_tab2", atan_tab2, sizeof (atan_tab2));
  509.     emit_angle  ("static", "FAR atan_tab3", atan_tab3, sizeof (atan_tab3));
  510.  
  511.     exit (0);
  512.     return (0);
  513. }
  514. #endif
  515.